import os
import urllib.request, sys
from json import dumps, loads
import sys
import urllib,socket,ssl
import hashlib
__author__ = 'LuckyHhy'

#读取文件
def ReadFile(filename,mode = 'r'):
    if not os.path.exists(filename): return False
    try:
        fp = open(filename, mode)
        f_body = fp.read()
        fp.close()
    except Exception as ex:
        if sys.version_info[0] != 2:
            try:
                fp = open(filename, mode,encoding="utf-8")
                f_body = fp.read()
                fp.close()
            except:
                fp = open(filename, mode,encoding="GBK")
                f_body = fp.read()
                fp.close()
        else:
            return False
    return f_body


# 下载文件进度回调
def DownloadHook(count, blockSize, totalSize):
    global pre
    used = count * blockSize
    pre1 = int((100.0 * used / totalSize))
    if pre == pre1:
        return
    speed = {'total': totalSize, 'used': used, 'pre': pre}
    WriteLogs(dumps(speed))
    pre = pre1


# 下载进度
def Schedule(blocknum, blocksize, totalsize):
    '''
    urllib.urlretrieve 的回调函数
    :param blocknum: 已经下载的数据块
    :param blocksize: 数据块的大小
    :param totalsize: 远程文件的大小
    :return:
    '''
    percent = 100.0 * blocknum * blocksize / totalsize
    if percent > 100:
        percent = 100
    s = ('#' * round(percent)).ljust(100, '-')
    sys.stdout.write("%.2f%%" % percent + '[ ' + s + ']' + '\r')
    sys.stdout.flush()


# 生成文件夹
def MakeDir(save_path):
    if not os.path.exists(save_path):
        os.makedirs(save_path)


# 下载文件
def DownloadFile(url, filename):
    try:
        socket.setdefaulttimeout(30)
        try:
            ssl._create_default_https_context = ssl._create_unverified_context
        except:
            pass
        urllib.request.urlretrieve(url, filename=filename, reporthook=DownloadHook)
        # 赋予文件夹权限
        os.system('chown www.www ' + filename)
        WriteLogs('done')
    except:
        WriteLogs('done')

#生成文件的MD5
def FileMd5(filename):
    """
        @name 生成文件的MD5
        @author hwliang<hwl@bt.cn>
        @param filename 文件名
        @return string(32) or False
    """
    if not os.path.isfile(filename): return False
    my_hash = hashlib.md5()
    f = open(filename,'rb')
    while True:
        b = f.read(8096)
        if not b :
            break
        my_hash.update(b)
    f.close()
    return my_hash.hexdigest()


# 计算文件数量
def GetFilesCount(path):
    i = 0
    for name in os.listdir(path): i += 1
    return i


# 字节单位转换
def ToSize( size):
    ds = ['b', 'KB', 'MB', 'GB', 'TB']
    for d in ds:
        if size < 1024: return str(size) + d
        size = size / 1024
    return '0b'

#取文件权限字符串
def GetFileMode(filename):
    """
        @name 取文件权限字符串
        @author hwliang<hwl@bt.cn>
        @param filename  文件全路径
        @return string  如：644/777/755
    """
    stat = os.stat(filename)
    accept = str(oct(stat.st_mode)[-3:])
    return accept


'''取文件或目录权限信息'''
def get_mode_and_user(path):
    if not os.path.exists(path): return None
    stat = os.stat(path)
    data = str(oct(stat.st_mode)[-3:])
    return data

# 写入日志
def WriteLogs(logMsg):
    try:
        global logPath
        with open(logPath, 'w+') as fp:
            fp.write(logMsg)
            fp.close()
    except:
        pass


#写入文件内容
def WriteFile(filename,s_body,mode='w+'):
    if not os.path.exists(filename):
        MakeDir(filename)
    try:
        fp = open(filename, mode)
        fp.write(s_body)
        fp.close()
        return True
    except:
        try:
            fp = open(filename, mode,encoding="utf-8")
            fp.write(s_body)
            fp.close()
            return True
        except:
            return False


# 取文件或目录大小
def GetPathSize(path, exclude=[]):
    """根据排除目录获取路径的总大小
    :path 目标路径
    :exclude 排除路径单个字符串或者多个列表。匹配路径是基于path的相对路径,规则是
        tar命令的--exclude规则的子集。
    """
    import fnmatch
    if not os.path.exists(path): return 0
    if not os.path.isdir(path): return os.path.getsize(path)
    if type(exclude) != type([]):
        exclude = [exclude]

    path = path[0:-1] if path[-1] == "/" else path
    path = os.path.normcase(path)
    # print("path:"+ path)
    # print("exclude:"+ str(exclude))
    _exclude = exclude[0:]
    for i, e in enumerate(_exclude):
        if not e.startswith(path):
            exclude.append(os.path.join(path, e))

    # print(exclude)
    total_size = 0
    count = 0
    for root, dirs, files in os.walk(path, topdown=True):
        # filter path
        for exc in exclude:
            for d in dirs:
                sub_dir = os.path.normcase(root + os.path.sep + d)
                if fnmatch.fnmatch(sub_dir, exc) or d == exc:
                    # print("排除目录:"+sub_dir)
                    dirs.remove(d)
        count += 1
        for f in files:
            to_exclude = False
            count += 1
            filename = os.path.normcase(root + os.path.sep + f)
            if not os.path.exists(filename): continue
            if os.path.islink(filename): continue
            # filter file
            norm_filename = os.path.normcase(filename)
            for fexc in exclude:
                if fnmatch.fnmatch(norm_filename, fexc) or fexc == f:
                    to_exclude = True
                    # print("排除文件:"+norm_filename)
                    break
            if to_exclude:
                continue
            total_size += os.path.getsize(filename)
    return total_size